package com.credithc.signature.common.utils;

import com.google.common.base.Function;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author: qiyc
 * @Date: 2019/12/18 16:55
 * @Description:
 */
public class LoadingCacheUtil<K, V> {
    public static final ExecutorService REFRESH_EXECUTOR = new ThreadPoolExecutor(1, Integer.MAX_VALUE, 1, TimeUnit.MINUTES, new LinkedBlockingQueue(), new ThreadPoolExecutor.CallerRunsPolicy());

    public static <K, V> LoadingCache<K, V> asyncReloadMin(Long maximumSize, CacheLoader cacheLoader) {
        return asyncReload(maximumSize, cacheLoader, 1, TimeUnit.MINUTES);
    }

    public static <K, V> LoadingCache<K, V> asyncReload(Long maximumSize, CacheLoader cacheLoader, long duration, TimeUnit unit) {
        CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder();
        if (maximumSize != null) {
            builder.maximumSize(maximumSize);
        }
        return builder.refreshAfterWrite(duration, unit).build(CacheLoader.asyncReloading(cacheLoader, REFRESH_EXECUTOR));
    }

    public static <K, V> LoadingCache<K, V> justLoad(Long maximumSize, CacheLoader cacheLoader) {
        CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder();
        if (maximumSize != null) {
            builder.maximumSize(maximumSize);
        }
        return builder.build(cacheLoader);
    }
}
